package com.jsbb.aspect;

import com.alibaba.fastjson.JSON;
import com.jsbb.annotation.ApiLog;
import com.jsbb.mapper.sys.SysLogMapper;
import com.jsbb.model.sys.SysLog;
import com.jsbb.util.IdWorkerUtils;
import com.jsbb.util.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 * 接口日志切面
 *
 * @author w
 * @date 2021-03-05
 */
@Slf4j
@Aspect
@Component
public class LogAspect {

    @Autowired
    private SysLogMapper sysLogMapper;

    /**
     * @Pointcut("@annotation(com.jsbb.annotation.ApiLog)")
     */
    @Pointcut("execution(public * com.jsbb.controller..*.*(..))")
    public void pointcut() {
    }

    /**
     * 环绕通知
     *
     * @param point
     * @return
     */
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) {
        long beginTime = System.currentTimeMillis();
        Object result = null;
        try {
            result = point.proceed();
            long time = System.currentTimeMillis() - beginTime;
            saveLog(point, time);
        } catch (Throwable throwable) {
            log.error("记录系统日志异常==={}", throwable.getMessage());
        }
        return result;
    }

    private void saveLog(ProceedingJoinPoint joinPoint, long time) {
        ApiLog apiLog = joinPoint.getTarget().getClass().getAnnotation(ApiLog.class);
        apiLog = apiLog == null ? ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(ApiLog.class) : apiLog;
        if (apiLog != null) {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            SysLog sysLog = new SysLog();
            sysLog.setId(IdWorkerUtils.idWorker.nextId());
            sysLog.setUserId(null);
            sysLog.setModule(apiLog.value());
            sysLog.setUrl(request.getRequestURI());
            sysLog.setParam(getParam(joinPoint));
            sysLog.setTime((int) time);
            sysLog.setIp(IpUtils.getIpAddress(request));
            sysLog.setCreateTime(new Date());
            sysLog.setUpdateTime(sysLog.getCreateTime());
            sysLogMapper.insertSelective(sysLog);
        }
    }

    private String getParam(ProceedingJoinPoint point) {
        String param = null;
        if (point.getArgs() != null) {
            Object object = point.getArgs()[0];
            if (object instanceof HttpServletRequest) {

            } else if (object instanceof HttpServletResponse) {

            } else {
                param = JSON.toJSONString(object);
            }
        }
        return param;
    }
}
